home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / binutils.252 / gas / config / obj-elf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-08  |  25.8 KB  |  1,078 lines

  1. /* ELF object file format
  2.    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GAS, the GNU Assembler.
  5.  
  6.    GAS is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as
  8.    published by the Free Software Foundation; either version 2,
  9.    or (at your option) any later version.
  10.  
  11.    GAS is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  14.    the GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public
  17.    License along with GAS; see the file COPYING.  If not, write
  18.    to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  19.  
  20. #include "as.h"
  21. #include "subsegs.h"
  22. #include "obstack.h"
  23.  
  24. #ifdef ECOFF_DEBUGGING
  25. #include "ecoff.h"
  26. #endif
  27.  
  28. #ifdef TC_MIPS
  29. #include "elf/mips.h"
  30. #endif
  31.  
  32. #ifdef ECOFF_DEBUGGING
  33. static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
  34. static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
  35. #endif
  36.  
  37. static void obj_elf_line PARAMS ((int));
  38. void obj_elf_version PARAMS ((int));
  39. static void obj_elf_size PARAMS ((int));
  40. static void obj_elf_type PARAMS ((int));
  41. static void obj_elf_ident PARAMS ((int));
  42. static void obj_elf_weak PARAMS ((int));
  43. static void obj_elf_local PARAMS ((int));
  44. static void obj_elf_common PARAMS ((int));
  45. static void obj_elf_data PARAMS ((int));
  46. static void obj_elf_text PARAMS ((int));
  47.  
  48. const pseudo_typeS obj_pseudo_table[] =
  49. {
  50.   {"comm", obj_elf_common, 0},
  51.   {"ident", obj_elf_ident, 0},
  52.   {"local", obj_elf_local, 0},
  53.   {"previous", obj_elf_previous, 0},
  54.   {"section", obj_elf_section, 0},
  55.   {"size", obj_elf_size, 0},
  56.   {"type", obj_elf_type, 0},
  57.   {"version", obj_elf_version, 0},
  58.   {"weak", obj_elf_weak, 0},
  59.  
  60. /* These are used for stabs-in-elf configurations.  */
  61.   {"line", obj_elf_line, 0},
  62.  
  63.   /* These are used for dwarf. */
  64.   {"2byte", cons, 2},
  65.   {"4byte", cons, 4},
  66.   {"8byte", cons, 8},
  67.  
  68.   /* We need to trap the section changing calls to handle .previous.  */
  69.   {"data", obj_elf_data, 0},
  70.   {"text", obj_elf_text, 0},
  71.  
  72. #ifdef ECOFF_DEBUGGING
  73.   /* COFF style debugging information for ECOFF. .ln is not used; .loc
  74.      is used instead.  */
  75.   { "def",    ecoff_directive_def,    0 },
  76.   { "dim",    ecoff_directive_dim,    0 },
  77.   { "endef",    ecoff_directive_endef,    0 },
  78.   { "file",    ecoff_directive_file,    0 },
  79.   { "scl",    ecoff_directive_scl,    0 },
  80.   { "tag",    ecoff_directive_tag,    0 },
  81.   { "val",    ecoff_directive_val,    0 },
  82.  
  83.   /* COFF debugging requires pseudo-ops .size and .type, but ELF
  84.      already has meanings for those.  We use .esize and .etype
  85.      instead.  These are only generated by gcc anyhow.  */
  86.   { "esize",    ecoff_directive_size,    0 },
  87.   { "etype",    ecoff_directive_type,    0 },
  88.  
  89.   /* ECOFF specific debugging information.  */
  90.   { "begin",    ecoff_directive_begin,    0 },
  91.   { "bend",    ecoff_directive_bend,    0 },
  92.   { "end",    ecoff_directive_end,    0 },
  93.   { "ent",    ecoff_directive_ent,    0 },
  94.   { "fmask",    ecoff_directive_fmask,    0 },
  95.   { "frame",    ecoff_directive_frame,    0 },
  96.   { "loc",    ecoff_directive_loc,    0 },
  97.   { "mask",    ecoff_directive_mask,    0 },
  98.  
  99.   /* These are used on Irix.  I don't know how to implement them.  */
  100.   { "alias",    s_ignore,        0 },
  101.   { "bgnb",    s_ignore,        0 },
  102.   { "endb",    s_ignore,        0 },
  103.   { "lab",    s_ignore,        0 },
  104.   { "noalias",    s_ignore,        0 },
  105.   { "verstamp",    s_ignore,        0 },
  106.   { "vreg",    s_ignore,        0 },
  107. #endif /* ECOFF_DEBUGGING */
  108.  
  109.   {NULL}            /* end sentinel */
  110. };
  111.  
  112. #undef NO_RELOC
  113. #include "aout/aout64.h"
  114.  
  115. void
  116. elf_file_symbol (s)
  117.      char *s;
  118. {
  119.   symbolS *sym;
  120.  
  121.   sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
  122.   sym->sy_frag = &zero_address_frag;
  123.   sym->bsym->flags |= BSF_FILE;
  124.  
  125.   if (symbol_rootP != sym)
  126.     {
  127.       symbol_remove (sym, &symbol_rootP, &symbol_lastP);
  128.       symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
  129. #ifdef DEBUG
  130.       verify_symbol_chain (symbol_rootP, symbol_lastP);
  131. #endif
  132.     }
  133. }
  134.  
  135. static void
  136. obj_elf_common (ignore)
  137.      int ignore;
  138. {
  139.   char *name;
  140.   char c;
  141.   char *p;
  142.   int temp, size;
  143.   symbolS *symbolP;
  144.   int have_align;
  145.  
  146.   name = input_line_pointer;
  147.   c = get_symbol_end ();
  148.   /* just after name is now '\0' */
  149.   p = input_line_pointer;
  150.   *p = c;
  151.   SKIP_WHITESPACE ();
  152.   if (*input_line_pointer != ',')
  153.     {
  154.       as_bad ("Expected comma after symbol-name");
  155.       ignore_rest_of_line ();
  156.       return;
  157.     }
  158.   input_line_pointer++;        /* skip ',' */
  159.   if ((temp = get_absolute_expression ()) < 0)
  160.     {
  161.       as_bad (".COMMon length (%d.) <0! Ignored.", temp);
  162.       ignore_rest_of_line ();
  163.       return;
  164.     }
  165.   size = temp;
  166.   *p = 0;
  167.   symbolP = symbol_find_or_make (name);
  168.   *p = c;
  169.   if (S_IS_DEFINED (symbolP))
  170.     {
  171.       as_bad ("Ignoring attempt to re-define symbol");
  172.       ignore_rest_of_line ();
  173.       return;
  174.     }
  175.   if (S_GET_VALUE (symbolP) != 0)
  176.     {
  177.       if (S_GET_VALUE (symbolP) != size)
  178.     {
  179.       as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
  180.            S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
  181.     }
  182.     }
  183.   know (symbolP->sy_frag == &zero_address_frag);
  184.   if (*input_line_pointer != ',')
  185.     have_align = 0;
  186.   else
  187.     {
  188.       have_align = 1;
  189.       input_line_pointer++;
  190.       SKIP_WHITESPACE ();
  191.     }
  192.   if (! have_align || *input_line_pointer != '"')
  193.     {
  194.       if (! have_align)
  195.     temp = 0;
  196.       else
  197.     {
  198.       temp = get_absolute_expression ();
  199.       if (temp < 0)
  200.         {
  201.           temp = 0;
  202.           as_warn ("Common alignment negative; 0 assumed");
  203.         }
  204.     }
  205.       if (symbolP->local)
  206.     {
  207.       segT old_sec;
  208.       int old_subsec;
  209.       char *pfrag;
  210.       int align;
  211.  
  212.     /* allocate_bss: */
  213.       old_sec = now_seg;
  214.       old_subsec = now_subseg;
  215.       align = temp;
  216.       record_alignment (bss_section, align);
  217.       subseg_set (bss_section, 0);
  218.       if (align)
  219.         frag_align (align, 0);
  220.       if (S_GET_SEGMENT (symbolP) == bss_section)
  221.         symbolP->sy_frag->fr_symbol = 0;
  222.       symbolP->sy_frag = frag_now;
  223.       pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
  224.                 (char *) 0);
  225.       *pfrag = 0;
  226.       S_SET_SEGMENT (symbolP, bss_section);
  227.       S_CLEAR_EXTERNAL (symbolP);
  228.       subseg_set (old_sec, old_subsec);
  229.     }
  230.       else
  231.     {
  232.     allocate_common:
  233.       S_SET_VALUE (symbolP, (valueT) size);
  234.       S_SET_ALIGN (symbolP, temp);
  235.       S_SET_EXTERNAL (symbolP);
  236.       /* should be common, but this is how gas does it for now */
  237.       S_SET_SEGMENT (symbolP, bfd_und_section_ptr);
  238.     }
  239.     }
  240.   else
  241.     {
  242.       input_line_pointer++;
  243.       /* @@ Some use the dot, some don't.  Can we get some consistency??  */
  244.       if (*input_line_pointer == '.')
  245.     input_line_pointer++;
  246.       /* @@ Some say data, some say bss.  */
  247.       if (strncmp (input_line_pointer, "bss\"", 4)
  248.       && strncmp (input_line_pointer, "data\"", 5))
  249.     {
  250.       while (*--input_line_pointer != '"')
  251.         ;
  252.       input_line_pointer--;
  253.       goto bad_common_segment;
  254.     }
  255.       while (*input_line_pointer++ != '"')
  256.     ;
  257.       goto allocate_common;
  258.     }
  259.   demand_empty_rest_of_line ();
  260.   return;
  261.  
  262.   {
  263.   bad_common_segment:
  264.     p = input_line_pointer;
  265.     while (*p && *p != '\n')
  266.       p++;
  267.     c = *p;
  268.     *p = '\0';
  269.     as_bad ("bad .common segment %s", input_line_pointer + 1);
  270.     *p = c;
  271.     input_line_pointer = p;
  272.     ignore_rest_of_line ();
  273.     return;
  274.   }
  275. }
  276.  
  277. static void 
  278. obj_elf_local (ignore)
  279.      int ignore;
  280. {
  281.   char *name;
  282.   int c;
  283.   symbolS *symbolP;
  284.  
  285.   do
  286.     {
  287.       name = input_line_pointer;
  288.       c = get_symbol_end ();
  289.       symbolP = symbol_find_or_make (name);
  290.       *input_line_pointer = c;
  291.       SKIP_WHITESPACE ();
  292.       S_CLEAR_EXTERNAL (symbolP);
  293.       symbolP->local = 1;
  294.       if (c == ',')
  295.     {
  296.       input_line_pointer++;
  297.       SKIP_WHITESPACE ();
  298.       if (*input_line_pointer == '\n')
  299.         c = '\n';
  300.     }
  301.     }
  302.   while (c == ',');
  303.   demand_empty_rest_of_line ();
  304. }
  305.  
  306. static void 
  307. obj_elf_weak (ignore)
  308.      int ignore;
  309. {
  310.   char *name;
  311.   int c;
  312.   symbolS *symbolP;
  313.  
  314.   do
  315.     {
  316.       name = input_line_pointer;
  317.       c = get_symbol_end ();
  318.       symbolP = symbol_find_or_make (name);
  319.       *input_line_pointer = c;
  320.       SKIP_WHITESPACE ();
  321.       S_SET_WEAK (symbolP);
  322.       symbolP->local = 1;
  323.       if (c == ',')
  324.     {
  325.       input_line_pointer++;
  326.       SKIP_WHITESPACE ();
  327.       if (*input_line_pointer == '\n')
  328.         c = '\n';
  329.     }
  330.     }
  331.   while (c == ',');
  332.   demand_empty_rest_of_line ();
  333. }
  334.  
  335. static segT previous_section;
  336. static int previous_subsection;
  337.  
  338. /* Handle the .section pseudo-op.  This code supports two different
  339.    syntaxes.  
  340.  
  341.    The first is found on Solaris, and looks like
  342.        .section ".sec1",#alloc,#execinstr,#write
  343.    Here the names after '#' are the SHF_* flags to turn on for the
  344.    section.  I'm not sure how it determines the SHT_* type (BFD
  345.    doesn't really give us control over the type, anyhow).
  346.  
  347.    The second format is found on UnixWare, and probably most SVR4
  348.    machines, and looks like
  349.        .section .sec1,"a",@progbits
  350.    The quoted string may contain any combination of a, w, x, and
  351.    represents the SHF_* flags to turn on for the section.  The string
  352.    beginning with '@' can be progbits or nobits.  There should be
  353.    other possibilities, but I don't know what they are.  In any case,
  354.    BFD doesn't really let us set the section type.  */
  355.  
  356. /* Certain named sections have particular defined types, listed on p.
  357.    4-19 of the ABI.  */
  358. struct special_section
  359. {
  360.   const char *name;
  361.   int type;
  362.   int attributes;
  363. };
  364.  
  365. static struct special_section special_sections[] =
  366. {
  367.   { ".bss",    SHT_NOBITS,    SHF_ALLOC + SHF_WRITE        },
  368.   { ".comment",    SHT_PROGBITS,    0                },
  369.   { ".data",    SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE        },
  370.   { ".data1",    SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE        },
  371.   { ".debug",    SHT_PROGBITS,    0                },
  372.   { ".fini",    SHT_PROGBITS,    SHF_ALLOC + SHF_EXECINSTR    },
  373.   { ".init",    SHT_PROGBITS,    SHF_ALLOC + SHF_EXECINSTR    },
  374.   { ".line",    SHT_PROGBITS,    0                },
  375.   { ".note",    SHT_NOTE,    0                },
  376.   { ".rodata",    SHT_PROGBITS,    SHF_ALLOC            },
  377.   { ".rodata1",    SHT_PROGBITS,    SHF_ALLOC            },
  378.   { ".text",    SHT_PROGBITS,    SHF_ALLOC + SHF_EXECINSTR    },
  379.  
  380. #ifdef ELF_TC_SPECIAL_SECTIONS
  381.   ELF_TC_SPECIAL_SECTIONS
  382. #endif
  383.  
  384. #if 0
  385.   /* The following section names are special, but they can not
  386.      reasonably appear in assembler code.  Some of the attributes are
  387.      processor dependent.  */
  388.   { ".dynamic",    SHT_DYNAMIC,    SHF_ALLOC /* + SHF_WRITE */     },
  389.   { ".dynstr",    SHT_STRTAB,    SHF_ALLOC            },
  390.   { ".dynsym",    SHT_DYNSYM,    SHF_ALLOC            },
  391.   { ".got",    SHT_PROGBITS,    0                },
  392.   { ".hash",    SHT_HASH,    SHF_ALLOC            },
  393.   { ".interp",    SHT_PROGBITS,    /* SHF_ALLOC */            },
  394.   { ".plt",    SHT_PROGBITS,    0                },
  395.   { ".shstrtab",SHT_STRTAB,    0                },
  396.   { ".strtab",    SHT_STRTAB,    /* SHF_ALLOC */            },
  397.   { ".symtab",    SHT_SYMTAB,    /* SHF_ALLOC */            },
  398. #endif
  399.  
  400.   { NULL,    0,        0                }
  401. };
  402.  
  403. void
  404. obj_elf_section (xxx)
  405.      int xxx;
  406. {
  407.   char *string;
  408.   int new_sec;
  409.   segT sec;
  410.   int type, attr;
  411.   int i;
  412.   flagword flags;
  413.  
  414.   /* Get name of section.  */
  415.   SKIP_WHITESPACE ();
  416.   if (*input_line_pointer == '"')
  417.     {
  418.       string = demand_copy_C_string (&xxx);
  419.       if (string == NULL)
  420.     {
  421.       ignore_rest_of_line ();
  422.       return;
  423.     }
  424.     }
  425.   else
  426.     {
  427.       char *p = input_line_pointer;
  428.       char c;
  429.       while (0 == strchr ("\n\t,; ", *p))
  430.     p++;
  431.       if (p == input_line_pointer)
  432.     {
  433.       as_warn ("Missing section name");
  434.       ignore_rest_of_line ();
  435.       return;
  436.     }
  437.       c = *p;
  438.       *p = 0;
  439.       string = xmalloc ((unsigned long) (p - input_line_pointer + 1));
  440.       strcpy (string, input_line_pointer);
  441.       *p = c;
  442.       input_line_pointer = p;
  443.     }
  444.  
  445.   /* Switch to the section, creating it if necessary.  */
  446.   previous_section = now_seg;
  447.   previous_subsection = now_subseg;
  448.  
  449.   new_sec = bfd_get_section_by_name (stdoutput, string) == NULL;
  450.   sec = subseg_new (string, 0);
  451.  
  452.   /* If this section already existed, we don't bother to change the
  453.      flag values.  */
  454.   if (! new_sec)
  455.     {
  456.       while (! is_end_of_line[(unsigned char) *input_line_pointer])
  457.     ++input_line_pointer;
  458.       ++input_line_pointer;
  459.       return;
  460.     }
  461.  
  462.   SKIP_WHITESPACE ();
  463.  
  464.   type = SHT_NULL;
  465.   attr = 0;
  466.  
  467.   if (*input_line_pointer == ',')
  468.     {
  469.       /* Skip the comma.  */
  470.       ++input_line_pointer;
  471.  
  472.       SKIP_WHITESPACE ();
  473.       if (*input_line_pointer == '"')
  474.     {
  475.       /* Pick up a string with a combination of a, w, x.  */
  476.       ++input_line_pointer;
  477.       while (*input_line_pointer != '"')
  478.         {
  479.           switch (*input_line_pointer)
  480.         {
  481.         case 'a':
  482.           attr |= SHF_ALLOC;
  483.           break;
  484.         case 'w':
  485.           attr |= SHF_WRITE;
  486.           break;
  487.         case 'x':
  488.           attr |= SHF_EXECINSTR;
  489.           break;
  490.         default:
  491.           as_warn ("Bad .section directive: want a,w,x in string");
  492.           ignore_rest_of_line ();
  493.           return;
  494.         }
  495.           ++input_line_pointer;
  496.         }
  497.  
  498.       /* Skip the closing quote.  */
  499.       ++input_line_pointer;
  500.  
  501.       SKIP_WHITESPACE ();
  502.       if (*input_line_pointer == ',')
  503.         {
  504.           ++input_line_pointer;
  505.           SKIP_WHITESPACE ();
  506.           if (*input_line_pointer == '@')
  507.         {
  508.           ++input_line_pointer;
  509.           if (strncmp (input_line_pointer, "progbits",
  510.                    sizeof "progbits" - 1) == 0)
  511.             {
  512.               type = SHT_PROGBITS;
  513.               input_line_pointer += sizeof "progbits" - 1;
  514.             }
  515.           else if (strncmp (input_line_pointer, "nobits",
  516.                     sizeof "nobits" - 1) == 0)
  517.             {
  518.               type = SHT_NOBITS;
  519.               input_line_pointer += sizeof "nobits" - 1;
  520.             }
  521.           else
  522.             {
  523.               as_warn ("Unrecognized section type");
  524.               ignore_rest_of_line ();
  525.             }
  526.         }
  527.         }
  528.     }
  529.       else
  530.     {
  531.       do
  532.         {
  533.           SKIP_WHITESPACE ();
  534.           if (*input_line_pointer != '#')
  535.         {
  536.           as_warn ("Bad .section directive");
  537.           ignore_rest_of_line ();
  538.           return;
  539.         }
  540.           ++input_line_pointer;
  541.           if (strncmp (input_line_pointer, "write",
  542.                sizeof "write" - 1) == 0)
  543.         {
  544.           attr |= SHF_WRITE;
  545.           input_line_pointer += sizeof "write" - 1;
  546.         }
  547.           else if (strncmp (input_line_pointer, "alloc",
  548.                 sizeof "alloc" - 1) == 0)
  549.         {
  550.           attr |= SHF_ALLOC;
  551.           input_line_pointer += sizeof "alloc" - 1;
  552.         }
  553.           else if (strncmp (input_line_pointer, "execinstr",
  554.                 sizeof "execinstr" - 1) == 0)
  555.         {
  556.           attr |= SHF_EXECINSTR;
  557.           input_line_pointer += sizeof "execinstr" - 1;
  558.         }
  559.           else
  560.         {
  561.           as_warn ("Unrecognized section attribute");
  562.           ignore_rest_of_line ();
  563.           return;
  564.         }
  565.           SKIP_WHITESPACE ();
  566.         }
  567.       while (*input_line_pointer++ == ',');
  568.       --input_line_pointer;
  569.     }
  570.     }
  571.  
  572.   /* See if this is one of the special sections.  */
  573.   for (i = 0; special_sections[i].name != NULL; i++)
  574.     {
  575.       if (string[1] == special_sections[i].name[1]
  576.       && strcmp (string, special_sections[i].name) == 0)
  577.     {
  578.       if (type == SHT_NULL)
  579.         type = special_sections[i].type;
  580.       else if (type != special_sections[i].type)
  581.         as_warn ("Setting incorrect section type for %s", string);
  582.  
  583.       if ((attr &~ special_sections[i].attributes) != 0)
  584.         as_warn ("Setting incorrect section attributes for %s", string);
  585.       attr |= special_sections[i].attributes;
  586.  
  587.       break;
  588.     }
  589.     }
  590.  
  591.   flags = (SEC_RELOC
  592.        | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
  593.        | ((attr & SHF_ALLOC) ? SEC_ALLOC | SEC_LOAD : 0)
  594.        | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0));
  595.   if (special_sections[i].name == NULL)
  596.     {
  597.       if (type == SHT_PROGBITS)
  598.     flags |= SEC_ALLOC | SEC_LOAD;
  599.       else if (type == SHT_NOBITS)
  600.     {
  601.       flags |= SEC_ALLOC;
  602.       flags &=~ SEC_LOAD;
  603.     }
  604.     }
  605.  
  606.   bfd_set_section_flags (stdoutput, sec, flags);
  607.  
  608.   demand_empty_rest_of_line ();
  609. }
  610.  
  611. /* Change to the .data section.  */
  612.  
  613. static void
  614. obj_elf_data (i)
  615.      int i;
  616. {
  617.   previous_section = now_seg;
  618.   previous_subsection = now_subseg;
  619.   s_data (i);
  620. }
  621.  
  622. /* Change to the .text section.  */
  623.  
  624. static void
  625. obj_elf_text (i)
  626.      int i;
  627. {
  628.   previous_section = now_seg;
  629.   previous_subsection = now_subseg;
  630.   s_text (i);
  631. }
  632.  
  633. void
  634. obj_elf_previous (ignore)
  635.      int ignore;
  636. {
  637.   if (previous_section == 0)
  638.     {
  639.       as_bad (".previous without corresponding .section; ignored");
  640.       return;
  641.     }
  642.   subseg_set (previous_section, previous_subsection);
  643.   previous_section = 0;
  644. }
  645.  
  646. static void
  647. obj_elf_line (ignore)
  648.      int ignore;
  649. {
  650.   /* Assume delimiter is part of expression.  BSD4.2 as fails with
  651.      delightful bug, so we are not being incompatible here. */
  652.   new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
  653.   demand_empty_rest_of_line ();
  654. }
  655.  
  656. void 
  657. obj_read_begin_hook ()
  658. {
  659. #ifdef ECOFF_DEBUGGING
  660.   ecoff_read_begin_hook ();
  661. #endif
  662. }
  663.  
  664. void 
  665. obj_symbol_new_hook (symbolP)
  666.      symbolS *symbolP;
  667. {
  668.   symbolP->sy_obj = 0;
  669.  
  670. #ifdef ECOFF_DEBUGGING
  671.   ecoff_symbol_new_hook (symbolP);
  672. #endif
  673. }
  674.  
  675. void 
  676. obj_elf_version (ignore)
  677.      int ignore;
  678. {
  679.   char *name;
  680.   unsigned int c;
  681.   char ch;
  682.   char *p;
  683.   asection *seg = now_seg;
  684.   subsegT subseg = now_subseg;
  685.   Elf_Internal_Note i_note;
  686.   Elf_External_Note e_note;
  687.   asection *note_secp = (asection *) NULL;
  688.   int i, len;
  689.  
  690.   SKIP_WHITESPACE ();
  691.   if (*input_line_pointer == '\"')
  692.     {
  693.       ++input_line_pointer;    /* -> 1st char of string. */
  694.       name = input_line_pointer;
  695.  
  696.       while (is_a_char (c = next_char_of_string ()))
  697.     ;
  698.       c = *input_line_pointer;
  699.       *input_line_pointer = '\0';
  700.       *(input_line_pointer - 1) = '\0';
  701.       *input_line_pointer = c;
  702.  
  703.       /* create the .note section */
  704.  
  705.       note_secp = subseg_new (".note", 0);
  706.       bfd_set_section_flags (stdoutput,
  707.                  note_secp,
  708.                  SEC_HAS_CONTENTS | SEC_READONLY);
  709.  
  710.       /* process the version string */
  711.  
  712.       len = strlen (name);
  713.  
  714.       i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
  715.       i_note.descsz = 0;    /* no description */
  716.       i_note.type = NT_VERSION;
  717.       p = frag_more (sizeof (e_note.namesz));
  718.       md_number_to_chars (p, (valueT) i_note.namesz, 4);
  719.       p = frag_more (sizeof (e_note.descsz));
  720.       md_number_to_chars (p, (valueT) i_note.descsz, 4);
  721.       p = frag_more (sizeof (e_note.type));
  722.       md_number_to_chars (p, (valueT) i_note.type, 4);
  723.  
  724.       for (i = 0; i < len; i++)
  725.     {
  726.       ch = *(name + i);
  727.       {
  728.         FRAG_APPEND_1_CHAR (ch);
  729.       }
  730.     }
  731.       frag_align (2, 0);
  732.  
  733.       subseg_set (seg, subseg);
  734.     }
  735.   else
  736.     {
  737.       as_bad ("Expected quoted string");
  738.     }
  739.   demand_empty_rest_of_line ();
  740. }
  741.  
  742. static void
  743. obj_elf_size (ignore)
  744.      int ignore;
  745. {
  746.   char *name = input_line_pointer;
  747.   char c = get_symbol_end ();
  748.   char *p;
  749.   expressionS exp;
  750.   symbolS *sym;
  751.  
  752.   p = input_line_pointer;
  753.   *p = c;
  754.   SKIP_WHITESPACE ();
  755.   if (*input_line_pointer != ',')
  756.     {
  757.       *p = 0;
  758.       as_bad ("expected comma after name `%s' in .size directive", name);
  759.       *p = c;
  760.       ignore_rest_of_line ();
  761.       return;
  762.     }
  763.   input_line_pointer++;
  764.   expression (&exp);
  765.   if (exp.X_op == O_absent)
  766.     {
  767.       as_bad ("missing expression in .size directive");
  768.       exp.X_op = O_constant;
  769.       exp.X_add_number = 0;
  770.     }
  771.   *p = 0;
  772.   sym = symbol_find_or_make (name);
  773.   *p = c;
  774.   if (exp.X_op == O_constant)
  775.     S_SET_SIZE (sym, exp.X_add_number);
  776.   else
  777.     {
  778.       sym->sy_obj = (expressionS *) xmalloc (sizeof (expressionS));
  779.       *sym->sy_obj = exp;
  780.     }
  781.   demand_empty_rest_of_line ();
  782. }
  783.  
  784. /* Handle the ELF .type pseudo-op.  This sets the type of a symbol.
  785.    There are three syntaxes.  The first (used on Solaris) is
  786.        .type SYM,#function
  787.    The second (used on UnixWare) is
  788.        .type SYM,@function
  789.    The third (reportedly to be used on Irix 6.0) is
  790.        .type SYM STT_FUNC
  791.  
  792.    FIXME: We do not fully support this pseudo-op.  In fact, the only
  793.    case we do support is setting the type to STT_FUNC, which we do by
  794.    setting the BSF_FUNCTION flag.  */
  795.  
  796. static void
  797. obj_elf_type (ignore)
  798.      int ignore;
  799. {
  800.   char *name;
  801.   char c;
  802.   int type;
  803.   const char *typename;
  804.   symbolS *sym;
  805.  
  806.   name = input_line_pointer;
  807.   c = get_symbol_end ();
  808.   sym = symbol_find_or_make (name);
  809.   *input_line_pointer = c;
  810.  
  811.   SKIP_WHITESPACE ();
  812.   if (*input_line_pointer == ',')
  813.     ++input_line_pointer;
  814.  
  815.   SKIP_WHITESPACE ();
  816.   if (*input_line_pointer == '#' || *input_line_pointer == '@')
  817.     ++input_line_pointer;
  818.  
  819.   typename = input_line_pointer;
  820.   c = get_symbol_end ();
  821.  
  822.   type = 0;
  823.   if (strcmp (typename, "function") == 0
  824.       || strcmp (typename, "STT_FUNC") == 0)
  825.     type = BSF_FUNCTION;
  826.   else if (strcmp (typename, "object") == 0
  827.        || strcmp (typename, "STT_OBJECT") == 0)
  828.     ;
  829.   else
  830.     as_bad ("ignoring unrecognized symbol type \"%s\"", typename);
  831.  
  832.   *input_line_pointer = c;
  833.  
  834.   sym->bsym->flags |= type;
  835.  
  836.   demand_empty_rest_of_line ();
  837. }
  838.  
  839. static void
  840. obj_elf_ident (ignore)
  841.      int ignore;
  842. {
  843.   static segT comment_section;
  844.   segT old_section = now_seg;
  845.   int old_subsection = now_subseg;
  846.  
  847.   if (!comment_section)
  848.     {
  849.       char *p;
  850.       comment_section = subseg_new (".comment", 0);
  851.       bfd_set_section_flags (stdoutput, comment_section,
  852.                  SEC_READONLY | SEC_HAS_CONTENTS);
  853.       p = frag_more (1);
  854.       *p = 0;
  855.     }
  856.   else
  857.     subseg_set (comment_section, 0);
  858.   stringer (1);
  859.   subseg_set (old_section, old_subsection);
  860. }
  861.  
  862. #ifdef INIT_STAB_SECTION
  863.  
  864. /* The first entry in a .stabs section is special.  */
  865.  
  866. void
  867. obj_elf_init_stab_section (seg)
  868.      segT seg;
  869. {
  870.   char *file;
  871.   char *p;
  872.   char *stabstr_name;
  873.   unsigned int stroff;
  874.  
  875.   /* Force the section to align to a longword boundary.  Without this,
  876.      UnixWare ar crashes.  */
  877.   bfd_set_section_alignment (stdoutput, seg, 2);
  878.  
  879.   /* Make space for this first symbol. */
  880.   p = frag_more (12);
  881.   /* Zero it out. */
  882.   memset (p, 0, 12);
  883.   as_where (&file, (unsigned int *) NULL);
  884.   stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
  885.   strcpy (stabstr_name, segment_name (seg));
  886.   strcat (stabstr_name, "str");
  887.   stroff = get_stab_string_offset (file, stabstr_name);
  888.   know (stroff == 1);
  889.   md_number_to_chars (p, stroff, 4);
  890.   seg_info (seg)->stabu.p = p;
  891. }
  892.  
  893. #endif
  894.  
  895. /* Fill in the counts in the first entry in a .stabs section.  */
  896.  
  897. static void
  898. adjust_stab_sections (abfd, sec, xxx)
  899.      bfd *abfd;
  900.      asection *sec;
  901.      PTR xxx;
  902. {
  903.   char *name;
  904.   asection *strsec;
  905.   char *p;
  906.   int strsz, nsyms;
  907.  
  908.   if (strncmp (".stab", sec->name, 5))
  909.     return;
  910.   if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
  911.     return;
  912.  
  913.   name = (char *) alloca (strlen (sec->name) + 4);
  914.   strcpy (name, sec->name);
  915.   strcat (name, "str");
  916.   strsec = bfd_get_section_by_name (abfd, name);
  917.   if (strsec)
  918.     strsz = bfd_section_size (abfd, strsec);
  919.   else
  920.     strsz = 0;
  921.   nsyms = bfd_section_size (abfd, sec) / 12 - 1;
  922.  
  923.   p = seg_info (sec)->stabu.p;
  924.   assert (p != 0);
  925.  
  926.   bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
  927.   bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
  928. }
  929.  
  930. #ifdef ECOFF_DEBUGGING
  931.  
  932. /* This function is called by the ECOFF code.  It is supposed to
  933.    record the external symbol information so that the backend can
  934.    write it out correctly.  The ELF backend doesn't actually handle
  935.    this at the moment, so we do it ourselves.  We save the information
  936.    in the symbol.  */
  937.  
  938. void
  939. obj_ecoff_set_ext (sym, ext)
  940.      symbolS *sym;
  941.      EXTR *ext;
  942. {
  943.   sym->bsym->udata = (PTR) ext;
  944. }
  945.  
  946. /* This function is called by bfd_ecoff_debug_externals.  It is
  947.    supposed to *EXT to the external symbol information, and return
  948.    whether the symbol should be used at all.  */
  949.  
  950. static boolean
  951. elf_get_extr (sym, ext)
  952.      asymbol *sym;
  953.      EXTR *ext;
  954. {
  955.   if (sym->udata == NULL)
  956.     return false;
  957.   *ext = *(EXTR *) sym->udata;
  958.   return true;
  959. }
  960.  
  961. /* This function is called by bfd_ecoff_debug_externals.  It has
  962.    nothing to do for ELF.  */
  963.  
  964. /*ARGSUSED*/
  965. static void
  966. elf_set_index (sym, indx)
  967.      asymbol *sym;
  968.      bfd_size_type indx;
  969. {
  970. }
  971.  
  972. #endif /* ECOFF_DEBUGGING */
  973.  
  974. void
  975. elf_frob_symbol (symp)
  976.      symbolS *symp;
  977. {
  978. #ifdef ECOFF_DEBUGGING
  979.   ecoff_frob_symbol (symp);
  980. #endif
  981.   if (symp->sy_obj)
  982.     {
  983.       switch (symp->sy_obj->X_op)
  984.     {
  985.     case O_subtract:
  986.       S_SET_SIZE (symp,
  987.               (S_GET_VALUE (symp->sy_obj->X_add_symbol)
  988.                + symp->sy_obj->X_add_number
  989.                - S_GET_VALUE (symp->sy_obj->X_op_symbol)));
  990.       break;
  991.     case O_constant:
  992.       S_SET_SIZE (symp,
  993.               (S_GET_VALUE (symp->sy_obj->X_add_symbol)
  994.                + symp->sy_obj->X_add_number));
  995.       break;
  996.     default:
  997.       as_bad (".size expression too complicated to fix up");
  998.       break;
  999.     }
  1000.     }
  1001.   free (symp->sy_obj);
  1002.   symp->sy_obj = 0;
  1003. }
  1004.  
  1005. void 
  1006. elf_frob_file ()
  1007. {
  1008.   bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
  1009.  
  1010. #ifdef elf_tc_final_processing
  1011.   elf_tc_final_processing ();
  1012. #endif
  1013.  
  1014. #ifdef ECOFF_DEBUGGING
  1015.   /* Generate the ECOFF debugging information.  */
  1016.   {
  1017.     const struct ecoff_debug_swap *debug_swap;
  1018.     struct ecoff_debug_info debug;
  1019.     char *buf;
  1020.     asection *sec;
  1021.  
  1022.     debug_swap
  1023.       = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
  1024.     know (debug_swap != (const struct ecoff_debug_swap *) NULL);
  1025.     ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
  1026.  
  1027.     /* Set up the pointers in debug.  */
  1028. #define SET(ptr, offset, type) \
  1029.     debug.ptr = (type) (buf + debug.symbolic_header.offset)
  1030.  
  1031.     SET (line, cbLineOffset, unsigned char *);
  1032.     SET (external_dnr, cbDnOffset, PTR);
  1033.     SET (external_pdr, cbPdOffset, PTR);
  1034.     SET (external_sym, cbSymOffset, PTR);
  1035.     SET (external_opt, cbOptOffset, PTR);
  1036.     SET (external_aux, cbAuxOffset, union aux_ext *);
  1037.     SET (ss, cbSsOffset, char *);
  1038.     SET (external_fdr, cbFdOffset, PTR);
  1039.     SET (external_rfd, cbRfdOffset, PTR);
  1040.     /* ssext and external_ext are set up just below.  */
  1041.  
  1042. #undef SET    
  1043.  
  1044.     /* Set up the external symbols.  */
  1045.     debug.ssext = debug.ssext_end = NULL;
  1046.     debug.external_ext = debug.external_ext_end = NULL;
  1047.     if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
  1048.                      elf_get_extr, elf_set_index))
  1049.       as_fatal ("Failed to set up debugging information: %s",
  1050.         bfd_errmsg (bfd_get_error ()));
  1051.  
  1052.     sec = bfd_get_section_by_name (stdoutput, ".mdebug");
  1053.     assert (sec != NULL);
  1054.  
  1055.     know (stdoutput->output_has_begun == false);
  1056.  
  1057.     /* We set the size of the section, call bfd_set_section_contents
  1058.        to force the ELF backend to allocate a file position, and then
  1059.        write out the data.  FIXME: Is this really the best way to do
  1060.        this?  */
  1061.     sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
  1062.  
  1063.     if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL,
  1064.                     (file_ptr) 0, (bfd_size_type) 0))
  1065.       as_fatal ("Can't start writing .mdebug section: %s",
  1066.         bfd_errmsg (bfd_get_error ()));
  1067.  
  1068.     know (stdoutput->output_has_begun == true);
  1069.     know (sec->filepos != 0);
  1070.  
  1071.     if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
  1072.                  sec->filepos))
  1073.       as_fatal ("Could not write .mdebug section: %s",
  1074.         bfd_errmsg (bfd_get_error ()));
  1075.   }
  1076. #endif /* ECOFF_DEBUGGING */
  1077. }
  1078.